#include "Common.h"

initSing(World);

void World::Init()
{
	if(m_isinit)
		return;
	Log->Success("World", "Beginning startup and loading...");
	new MiscManager;
	new ScriptMgr;
	new ChatHandler;
	new TaxiHandler;
	new QuestHandler;
	new InterfaceHandler;
	new LfgSystem;
	new CalendarManager;
	InterfaceHandler::getSingle();
	m_isinit = true;
	miscmgr->LoadDBC();
	miscmgr->LoadPlayers();
	miscmgr->LoadItems();
	miscmgr->LoadTrainers();
	miscmgr->LoadGuards();
	miscmgr->LoadQuests();
	miscmgr->LoadWayPoints();
	new DatabaseLocalisation;
	sDatabaseLocal.LoadGossipLocals();
	sDatabaseLocal.LoadItemLocals();
	sDatabaseLocal.LoadNpcLocals();
	sQuestHandler.LoadQuestRelations();
	printf("\n");
	sTaxiHandler.LoadPathes();
	printf("\n");
	miscmgr->LoadNpcs();
	miscmgr->LoadGameObjects();
	printf("\n");
	//miscmgr->LoadMaps();
	printf("\n");
	Log->Warning("Master", "Precaching NPCs and GOs in background. During this time the server uses massive ressources!");
	printf("\n");
	ScriptMgr::getSingle()->LoadScripts();
	motd = world_config->GetChar("General Settings", "MOTD");
	annh = world_config->GetChar("General Settings", "ANNH");
	anna = world_config->GetChar("General Settings", "ANNA");
	autosavenpc = world_config->GetBool("General Settings", "AutoSaveNpc", true);
	autosavego = world_config->GetBool("General Settings", "AutoSaveGameobjects", false);
	autodeletenpc = world_config->GetBool("General Settings", "AutoDeleteNpc", false);
	autodeletego = world_config->GetBool("General Settings", "AutoDeleteGo", false);
	checkareaonmove = world_config->GetBool("General Settings", "CheckAreaOnMove", false);
	Spell::InitTable();
}

MapHandler* World::GetMapHandler(ui32 mapid)
{
	if(m_maphandlers.find(mapid) == m_maphandlers.end())
		return NULL;
	return m_maphandlers.find(mapid)->second;
}

void World::SendWorldText(const char* message, ...)
{
	RealmPacket data(SMSG_MESSAGECHAT);
	ScopedAllocator<char> vsmessage(255);
	va_list var;
	va_start(var, message);
	vsprintf(vsmessage, message, var);
	va_end(var);
	sChatHandler->BuildSystemPacket(vsmessage, &data);
	ScopedLock<Mutex> l(m_sessionlock);
	stdext::hash_map<ui32, Session*>::iterator itr = m_activesessions.begin();
	stdext::hash_map<ui32, Session*>::iterator end = m_activesessions.end();

	for( ; itr != end; ++itr)
		itr->second->SendPacket(&data);
}

void World::SendWorldTextToHorde(const char* message, ...)
{
	RealmPacket data(SMSG_MESSAGECHAT);
	ScopedAllocator<char> vsmessage(255);
	va_list var;
	va_start(var, message);
	vsprintf(vsmessage, message, var);
	va_end(var);
	sChatHandler->BuildSystemPacket(vsmessage, &data);
	ScopedLock<Mutex> l(m_sessionlock);
	stdext::hash_map<ui32, Session*>::iterator itr = m_activesessions.begin();
	stdext::hash_map<ui32, Session*>::iterator end = m_activesessions.end();

	for( ; itr != end; ++itr)
	{
		Player* plr = itr->second->GetPlayer();
		if(!plr)
			continue;
		if(plr->GetHorde())
			plr->GetSession()->SendPacket(&data);
	}
}

void World::SendWorldTextToAlliance(const char* message, ...)
{
	RealmPacket data(SMSG_MESSAGECHAT);
	ScopedAllocator<char> vsmessage(255);
	va_list var;
	va_start(var, message);
	vsprintf(vsmessage, message, var);
	va_end(var);
	sChatHandler->BuildSystemPacket(vsmessage, &data);
	ScopedLock<Mutex> l(m_sessionlock);
	stdext::hash_map<ui32, Session*>::iterator itr = m_activesessions.begin();
	stdext::hash_map<ui32, Session*>::iterator end = m_activesessions.end();

	for( ; itr != end; ++itr)
	{
		Player* plr = itr->second->GetPlayer();
		if(!plr)
			continue;
		if(!plr->GetHorde())
			plr->GetSession()->SendPacket(&data);
	}
}

void World::SendWorldScreenText(const char* message, ...)
{
	RealmPacket data(SMSG_AREA_TRIGGER_MESSAGE);
	ScopedAllocator<char> vsmessage(255);
	va_list var;
	va_start(var, message);
	vsprintf(vsmessage, message, var);
	va_end(var);
	data << ui32(0) << (char*)vsmessage << ui8(0);
	ScopedLock<Mutex> l(m_sessionlock);
	stdext::hash_map<ui32, Session*>::iterator itr = m_activesessions.begin();
	stdext::hash_map<ui32, Session*>::iterator end = m_activesessions.end();

	for( ; itr != end; ++itr)
		itr->second->SendPacket(&data);
}

void World::AddActiveSession(Session* sess)
{
	ScopedLock<Mutex> l(m_sessionlock);
	if(sess->GetAccountId())
		m_activesessions[sess->GetAccountId()] = sess;
}

void World::RemoveSession(ui32 accountid)
{
	ScopedLock<Mutex> l(m_sessionlock);
	m_activesessions[accountid] = 0;
}